/*
 * @brief: 
 * @Author: TzzzT
 * @Date: 2022-05-08 11:32:55
 * @LastEditTime: 2022-06-07 15:03:15
 * @LastEditors: TzzzT
 */


#include <stdio.h>
#include <time.h>
#include <sys/time.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "unity.h"

#include "esp_log.h"
#include "ssd1306.h"
#include "ssd1306_fonts.h"


#include "RCS_scr.h"
#include "RCS_master.h"





static const char *TAG = "ssd1306 test";

static ssd1306_handle_t dev = NULL;
time_t g_now;

extern rcs_system_t rcsSystem;




/*
2
2
16
2
2
16
2
2
16
2
2
*/
static esp_err_t scr_wait_game_start(ssd1306_handle_t dev){

    ssd1306_draw_string(dev, 20, 4, (const uint8_t*)"IMEI:", 16, 1);
    ssd1306_draw_num(dev, 60, 4, rcsSystem.player.id, 6, 16);

    ssd1306_draw_string(dev, 20, 24, (const uint8_t*)"DEVICE:", 16, 1);
    ssd1306_draw_num(dev, 76, 24, 1, 1, 16);

    ssd1306_draw_string(dev, 20, 44, (const uint8_t*)"BATTERY:", 16, 1);
    ssd1306_draw_num(dev, 84, 44, 56, 2, 16);

    return ssd1306_refresh_gram(dev);
}

static const uint8_t dead_convert[256];
static const uint8_t dead[256];
static const uint8_t hp_img[128];

#define Y_1 2
#define SIZE_1 12
#define SIZE_1_Y SIZE_1
#define SIZE_1_X (SIZE_1/2)
#define BULLET_NUM_X 0
#define TEAM_X 36
#define ROOM_X 64
#define DEVICE_NUM_X 96

#define HP_IMG_X 10
#define HP_IMG_Y 16

#define HP_X (HP_IMG_X + 32 + 12)


#define Y_2 50
#define DAMAGE_X 0
#define BATTERY_X 64

static esp_err_t scr_gaming_living(ssd1306_handle_t dev){
    ssd1306_draw_string(dev, BULLET_NUM_X, Y_1, (const uint8_t*)"B:", SIZE_1, 1);
    ssd1306_draw_num(dev, BULLET_NUM_X + SIZE_1_X*2, Y_1, rcsSystem.player.bullet_nums, 3, SIZE_1);

    ssd1306_draw_string(dev, TEAM_X, Y_1, (const uint8_t*)"T:", SIZE_1, 1);
    ssd1306_draw_num(dev, TEAM_X + SIZE_1_X*2, Y_1, rcsSystem.player.team, 1, SIZE_1);

    ssd1306_draw_string(dev, ROOM_X, Y_1, (const uint8_t*)"R:", SIZE_1, 1);
    ssd1306_draw_num(dev, ROOM_X + SIZE_1_X*2, Y_1, rcsSystem.player.room, 1, SIZE_1);

    ssd1306_draw_string(dev, DEVICE_NUM_X, Y_1, (const uint8_t*)"D:", SIZE_1, 1);
    ssd1306_draw_num(dev, DEVICE_NUM_X+ SIZE_1_X*2, Y_1, rcsSystem.display.conn_dev_num, 1, SIZE_1);

    ssd1306_draw_bitmap(dev, HP_IMG_X, HP_IMG_Y, &hp_img[0], 32, 32);

    ssd1306_draw_3216char(dev, HP_X, HP_IMG_Y, '1');
    ssd1306_draw_3216char(dev, HP_X+16, HP_IMG_Y, '5');
    ssd1306_draw_3216char(dev, HP_X+16*2, HP_IMG_Y, '0');
    ssd1306_draw_3216char(dev, HP_X+16*3, HP_IMG_Y, '0');


    ssd1306_draw_string(dev, DAMAGE_X, Y_2, (const uint8_t*)"DAM:", SIZE_1, 1);
    ssd1306_draw_num(dev, DAMAGE_X + SIZE_1_X*4, Y_2, rcsSystem.player.room, 4, SIZE_1);

    ssd1306_draw_string(dev, BATTERY_X, Y_2, (const uint8_t*)"BAT:", SIZE_1, 1);
    ssd1306_draw_num(dev, BATTERY_X + SIZE_1_X*4, Y_2, rcsSystem.device.battery, 3, SIZE_1);

    return ssd1306_refresh_gram(dev);
}




esp_err_t scr_gaming_dead(ssd1306_handle_t dev){
    ssd1306_draw_string(dev, BULLET_NUM_X, Y_1, (const uint8_t*)"B:", SIZE_1, 1);
    ssd1306_draw_num(dev, BULLET_NUM_X + SIZE_1_X*2, Y_1, rcsSystem.player.bullet_nums, 3, SIZE_1);

    ssd1306_draw_string(dev, TEAM_X, Y_1, (const uint8_t*)"T:", SIZE_1, 1);
    ssd1306_draw_num(dev, TEAM_X + SIZE_1_X*2, Y_1, rcsSystem.player.team, 1, SIZE_1);

    ssd1306_draw_string(dev, ROOM_X, Y_1, (const uint8_t*)"R:", SIZE_1, 1);
    ssd1306_draw_num(dev, ROOM_X + SIZE_1_X*2, Y_1, rcsSystem.player.room, 1, SIZE_1);

    ssd1306_draw_string(dev, DEVICE_NUM_X, Y_1, (const uint8_t*)"D:", SIZE_1, 1);
    ssd1306_draw_num(dev, DEVICE_NUM_X+ SIZE_1_X*2, Y_1, rcsSystem.display.conn_dev_num, 1, SIZE_1);

    static bool convert_flag = false;
    if (convert_flag){
        ssd1306_draw_bitmap(dev, 32, 20, &dead_convert[0], 64, 32);
    }else{
        ssd1306_draw_bitmap(dev, 32, 20, &dead[0], 64, 32);
    }
    convert_flag = !convert_flag;
    return ssd1306_refresh_gram(dev);
}



/******** Test Function ****************/
esp_err_t ssd1306_show_time(ssd1306_handle_t dev)
{
    struct tm timeinfo;
    char strftime_buf[64];
    time(&g_now);
    g_now++;
    setenv("TZ", "GMT-8", 1);
    tzset();
    localtime_r(&g_now, &timeinfo);
    strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);

    ssd1306_draw_3216char(dev, 0, 16, strftime_buf[11]);
    ssd1306_draw_3216char(dev, 16, 16, strftime_buf[12]);
    ssd1306_draw_3216char(dev, 32, 16, strftime_buf[13]);
    ssd1306_draw_3216char(dev, 48, 16, strftime_buf[14]);
    ssd1306_draw_3216char(dev, 64, 16, strftime_buf[15]);
    ssd1306_draw_1616char(dev, 80, 32, strftime_buf[16]);
    ssd1306_draw_1616char(dev, 96, 32, strftime_buf[17]);
    ssd1306_draw_1616char(dev, 112, 32, strftime_buf[18]);

    char *day = strftime_buf;
    day[3] = '\0';
    ssd1306_draw_string(dev, 87, 16, (const uint8_t *)day, 14, 1);
    ssd1306_draw_string(dev, 0, 52, (const uint8_t *)"MUSIC", 12, 0);
    ssd1306_draw_string(dev, 52, 52, (const uint8_t *)"MENU", 12, 0);
    ssd1306_draw_string(dev, 98, 52, (const uint8_t *)"PHONE", 12, 0);

    return ssd1306_refresh_gram(dev);
}

esp_err_t ssd1306_show_signs(ssd1306_handle_t dev)
{
    ssd1306_clear_screen(dev, 0x00);

    ssd1306_draw_bitmap(dev, 0, 2, &c_chSingal816[0], 16, 8);
    ssd1306_draw_bitmap(dev, 24, 2, &c_chBluetooth88[0], 8, 8);
    ssd1306_draw_bitmap(dev, 40, 2, &c_chMsg816[0], 16, 8);
    ssd1306_draw_bitmap(dev, 64, 2, &c_chGPRS88[0], 8, 8);
    ssd1306_draw_bitmap(dev, 90, 2, &c_chAlarm88[0], 8, 8);
    ssd1306_draw_bitmap(dev, 112, 2, &c_chBat816[0], 16, 8);

    return ssd1306_refresh_gram(dev);
}
/**
 * @brief i2c master initialization
 */
static void i2c_bus_init(void)
{
    i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
    conf.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL;

    esp_err_t ret = i2c_param_config(I2C_MASTER_NUM, &conf);
    TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, ret, "I2C config returned error");

    ret = i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);
    TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, ret, "I2C install returned error");
}

static void dev_ssd1306_initialization(void)
{
    esp_err_t ret;

    ESP_LOGI(TAG, "OLED initialization");
    i2c_bus_init();
    dev = ssd1306_create(I2C_MASTER_NUM, SSD1306_I2C_ADDRESS);
    TEST_ASSERT_NOT_NULL_MESSAGE(dev, "SSD1306 create returned error");

    ret = ssd1306_refresh_gram(dev);
    TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, ret, "SSD1306 refresh gram returned error");

    ret = ssd1306_show_signs(dev);
    TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, ret, "SSD1306 show signs returned error");
}

static void ssd1306_test_task(void *pvParameters)
{
    esp_err_t ret;

    ESP_LOGI(TAG, "OLED task start");
    dev_ssd1306_initialization();

    ssd1306_clear_screen(dev, 0);
    scr_gaming_living(dev);
    vTaskDelay(pdMS_TO_TICKS(1000));
    while (1) {
        ssd1306_clear_screen(dev, 0);
        ret = scr_gaming_dead(dev);
        TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, ret, "SSD1306 refresh gram returned error");
        vTaskDelay(pdMS_TO_TICKS(500));
    }




    ESP_LOGI(TAG, "OLED cleaning-up...");
    ssd1306_delete(dev);
    ret = i2c_driver_delete(I2C_MASTER_NUM);
    TEST_ASSERT_EQUAL(ESP_OK, ret);

    vTaskDelete(NULL);
}

void scr_test(void)
{
    ESP_LOGI("Device ssd1306 test", "[ssd1306][iot][device]");

    xTaskCreate(ssd1306_test_task, "ssd1306_test_task", 2048 * 2, NULL, 5, NULL);
}

static const uint8_t dead[256] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x3f,0xe0,0x1f,0xf8,0x0f,0x00,0x7f,0xc0,
                            0x3f,0xf8,0x1f,0xf8,0x0f,0x00,0x7f,0xf0,
                            0x38,0x1c,0x1c,0x00,0x1f,0x80,0x70,0x38,
                            0x38,0x0e,0x1c,0x00,0x19,0x80,0x70,0x1c,
                            0x38,0x07,0x1c,0x00,0x19,0x80,0x70,0x0e,
                            0x38,0x07,0x1c,0x00,0x39,0xc0,0x70,0x0e,
                            0x38,0x07,0x1f,0xf0,0x30,0xc0,0x70,0x0e,
                            0x38,0x07,0x1f,0xf0,0x30,0xc0,0x70,0x0e,
                            0x38,0x07,0x1c,0x00,0x7f,0xe0,0x70,0x0e,
                            0x38,0x0e,0x1c,0x00,0x7f,0xe0,0x70,0x1c,
                            0x38,0x0e,0x1c,0x00,0xe0,0x70,0x70,0x1c,
                            0x38,0x3c,0x1c,0x00,0xe0,0x70,0x70,0x78,
                            0x3f,0xf8,0x1f,0xf8,0xc0,0x30,0x7f,0xf0,
                            0x3f,0xe0,0x1f,0xf9,0xc0,0x38,0x7f,0xc0,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };

static const uint8_t dead_convert[256] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xc0,0x1f,0xe0,0x07,0xf0,0xff,0x80,0x3f,
                                        0xc0,0x07,0xe0,0x07,0xf0,0xff,0x80,0x0f,
                                        0xc7,0xe3,0xe3,0xff,0xe0,0x7f,0x8f,0xc7,
                                        0xc7,0xf1,0xe3,0xff,0xe6,0x7f,0x8f,0xe3,
                                        0xc7,0xf8,0xe3,0xff,0xe6,0x7f,0x8f,0xf1,
                                        0xc7,0xf8,0xe3,0xff,0xc6,0x3f,0x8f,0xf1,
                                        0xc7,0xf8,0xe0,0x0f,0xcf,0x3f,0x8f,0xf1,
                                        0xc7,0xf8,0xe0,0x0f,0xcf,0x3f,0x8f,0xf1,
                                        0xc7,0xf8,0xe3,0xff,0x80,0x1f,0x8f,0xf1,
                                        0xc7,0xf1,0xe3,0xff,0x80,0x1f,0x8f,0xe3,
                                        0xc7,0xf1,0xe3,0xff,0x1f,0x8f,0x8f,0xe3,
                                        0xc7,0xc3,0xe3,0xff,0x1f,0x8f,0x8f,0x87,
                                        0xc0,0x07,0xe0,0x07,0x3f,0xcf,0x80,0x0f,
                                        0xc0,0x1f,0xe0,0x06,0x3f,0xc7,0x80,0x3f,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
                                        0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };

static const uint8_t hp_img[128] = { 0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,
                                0x00,0xc0,0x03,0x00,0x00,0xc0,0x03,0x00,
                                0x00,0xcf,0xf3,0x00,0x00,0xcf,0xf3,0x00,
                                0x00,0xcf,0xf3,0x00,0x00,0xcf,0xf3,0x00,
                                0xff,0xcf,0xf3,0xff,0xff,0xcf,0xf3,0xff,
                                0xc0,0x0f,0xf0,0x03,0xc0,0x0f,0xf0,0x03,
                                0xcf,0xff,0xff,0xf3,0xcf,0xff,0xff,0xf3,
                                0xcf,0xff,0xff,0xf3,0xcf,0xff,0xff,0xf3,
                                0xcf,0xff,0xff,0xf3,0xcf,0xff,0xff,0xf3,
                                0xcf,0xff,0xff,0xf3,0xcf,0xff,0xff,0xf3,
                                0xc0,0x0f,0xf0,0x03,0xc0,0x0f,0xf0,0x03,
                                0xff,0xcf,0xf3,0xff,0xff,0xcf,0xf3,0xff,
                                0x00,0xcf,0xf3,0x00,0x00,0xcf,0xf3,0x00,
                                0x00,0xcf,0xf3,0x00,0x00,0xcf,0xf3,0x00,
                                0x00,0xc0,0x03,0x00,0x00,0xc0,0x03,0x00,
                                0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00 };


